/*
 * TowerRedOne.cs
 *
 * Created on December 9, 2007, 2:13 PM
 *
 * Copyright (C) 2007-2008  Hylke van der Schaaf
 * Copyright (C) 2010       Mathijs Miermans
 * 
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, in version 3 of the License.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 * 
 */

using System;
using System.Windows;
using System.Windows.Media;
using System.Windows.Shapes;
using System.Windows.Controls;

using HexTD.hex;
using HexTD.sprite;
using HexTD.util;

namespace HexTD.tower
{
	public class TowerRedOne : TowerBase
	{

		public static int price = 200;
		public static int damage = 35;
		public static float range = 5f;
		public static float spreadRadiusBase = 2.75f;

		private int fireAt = -1;
		private float enemyX = 0;
		private float enemyY = 0;
		private EnemySprite enemy;
		private COLOR damageColor = COLOR.RED;
		private int coolDown = 0;
		private int coolDownMax = 4;

		private Color transColor;
		private EllipseGeometry spread;
		private float spreadRadius;
		private float spreadRadius2;

		private EnemySprite[] currentTargets;

		/** Creates a new instance of TowerRedOne */
		public TowerRedOne(Context context, Hex hex)
			: base(TowerFactory.type.redOne, price, damage, range)
		{
			this.lineColor = Colors.Red;
			this.transColor = Color.FromArgb(75, this.lineColor.R, this.lineColor.G, this.lineColor.B);
			this.doInit(context, hex);
		}

		public override void doTick(int gameTime)
		{
			if (this.coolDown > 0)
			{
				this.coolDown--;
				if (this.coolDown > 3)
				{
					float radius = this.spreadRadius * (this.coolDown - 3) / 2;
					this.spread = new EllipseGeometry();
					this.spread.Center = new Point(this.enemy.getPaintX() - radius, this.enemy.getPaintY() - radius);
					this.spread.RadiusX = radius * 2;
					this.spread.RadiusY = radius * 2;
				}
			}
			else
			{
				int enemyNr = this.findEnemy(this.fireAt, false);
				this.fireAt = enemyNr;

				if (enemyNr >= 0)
				{
					float dx, dy, r;
					int splashDamage;

					this.enemy = this.context.enemies[enemyNr];
					this.enemyX = this.enemy.getX();
					this.enemyY = this.enemy.getY();
					this.currentTargets = this.findEnemiesInRange(this.enemyX, this.enemyY, this.spreadRadius);
					EnemySprite enemy2;
					for (int i = 0; i < this.currentTargets.Length; i++)
					{
						enemy2 = this.currentTargets[i];
						dx = this.enemyX - enemy2.getX();
						dy = this.enemyY - enemy2.getY();
						r = (float)Math.Sqrt(dx * dx + dy * dy);
						splashDamage = (int)Math.Round(this.damageCurrent * (1 - r / this.spreadRadius));
						enemy2.doDamage(splashDamage, this.damageColor);
					}

					//System.Diagnostics.Debug.WriteLine("TR! fire at tick: "+gameTime);
					this.coolDown = this.coolDownMax;
					this.spread = new EllipseGeometry();
					this.spread.Center = new Point((this.enemy.getPaintX() - this.spreadRadius) * paintScale, (this.enemy.getPaintY() - this.spreadRadius) * paintScale);
					this.spread.RadiusX = spreadRadius * 2 * paintScale;
					this.spread.RadiusY = spreadRadius * 2 * paintScale;
				}
			}
		}

		public override string getStatusString()
		{
			string retString = "";
			retString += "<h1>Red Tower 1</h1>" +
					"<p>" +
					"<b>Level:</b> " + (1 + this.level) + "<br>\n" +
					"<b>Damage:</b> " + this.damageText + "<br>\n" +
					"<b>Range:</b> " + this.rangeText + "<br>" +
					"</p>\n";
			return retString;
		}

		public override string getInfoString()
		{
			string retString = "";
			retString += "<h1>Red Tower 1</h1>" +
					"<p>" +
					"Tower with one laser. " +
					"The impact of this laser does splash damage to all enemies surrounding the target." +
					"<br>Strong against red enemies, very weak against green enemies." +
					"</p>" +
					"<p>" +
					"<b>Price:</b> " + TowerRedOne.price + "<br>" +
					"<b>Damage:</b> " + this.damageCurrent + " + splash<br>" +
					"<b>Range:</b> " + rangeCurrent.ToString(form) + "<br>" +
					"<b>Refire rate:</b> 4/s" +
					"</p>";
			return retString;
		}

		protected override void generateShapes()
		{
#if PORT
			int shapeCount = 3;
			this.shapes = new Shape[shapeCount];
			this.shapes[0] = new Ellipse.Float(-0.5f * this.paintScale, -0.5f * this.paintScale, 1.0f * this.paintScale, 1.0f * this.paintScale);
			this.shapes[1] = new Ellipse.Float(-0.5f * this.paintScale, -0.5f * this.paintScale, 1.0f * this.paintScale, 1.0f * this.paintScale);
			this.shapes[2] = new Ellipse.Float(-1.0f * this.context.strokeScale, -1.0f * this.context.strokeScale, 2.0f * this.context.strokeScale, 2.0f * this.context.strokeScale);

			this.shapeAction = new int[shapeCount];
			this.shapeAction[0] = 2;
			this.shapeAction[1] = 1;
			this.shapeAction[2] = 1;

			this.shapeColor = new Color[shapeCount];
			this.shapeColor[0] = this.transColor;
			this.shapeColor[1] = this.lineColor;
			this.shapeColor[2] = this.lineColor;

			this.strokes = new Brush[shapeCount];
			this.strokes[0] = new Brush(2.0f * this.context.strokeScale, Brush.CAP_ROUND, Brush.JOIN_BEVEL);
			this.strokes[1] = this.strokes[0];
			this.strokes[2] = this.strokes[0];
			this.spreadRadius = TowerRedOne.spreadRadiusBase;
			this.spreadRadius2 = this.spreadRadius * this.spreadRadius;
#endif
		}

		public override void paintEffects(Canvas g2, int gameTime)
		{
#if PORT
			Brush defaultStroke = g2.getStroke();

			if (this.fireAt > -1 && this.coolDown == this.coolDownMax)
			{
				g2.setColor(this.lineColor);
				float ex = this.enemy.getPaintX() + ((float)(Math.random() - 0.5) * this.paintScale / 10f);
				float ey = this.enemy.getPaintY() + ((float)(Math.random() - 0.5) * this.paintScale / 10f);
				g2.draw(new LineSegment.Float(this.xPaint, this.yPaint, ex, ey));
				for (int i = 0; i < this.currentTargets.Length; i++)
				{
					g2.draw(new LineSegment.Float(ex, ey, currentTargets[i].getPaintX(), currentTargets[i].getPaintY()));
				}
			}
			if (this.coolDown > this.coolDownMax - 1)
			{
				g2.setColor(this.transColor);
				g2.draw(this.spread);
			}

			g2.setStroke(defaultStroke);
#endif
		}
	}
}